package main

import "fmt"

/*
Go语言的内置错误接口
Go语言通过内置的错误接口提供了非常简单的错误处理机制。
error 类型 是一个内置的接口类型，这是他在源码中的定义：
//error 接口内后一个返回字符串的方法error()
type error interface{
	Error() string
}
error 是一个带有Error()方法的接口类型，这意味着你可以自己去实现这个接口
error 接口内只有一个Error()，只要实现了这个方法，就是实现了error

实现Go的内置错误接口
我们可以在编码中通过 实现 error 接口类型 （即实现error接口中的方法）来生成错误信息。
一下展示了三个错误生成方法，从基础到高级，推荐第三种方法。
*/

// 方法一： 在Error()方法中返回错误信息
// 自定义了一个fileError 类型 ，实现了error
//type fileError struct {
//}
//
//// 在结构体 fileError 上实现 Error() 方法， 相当于实现了error接口
//func (fe *fileError) Error() string {
//	return "文件错误"
//}
//
//// 经过上面两步我们已经实现了error这一接口数据类型
//func main() {
//	conent, err := openFile()
//	if err != nil {
//		fmt.Println(err)
//	} else {
//		fmt.Println(string(conent))
//	}
//
//}
//
//// 模拟一个错误
//func openFile() ([]byte, error) { //返回一个error类型的值
//	return nil, &fileError{}
//}

//像以上这样编码存在一个问题：
//在实际的使用过程中，我们可能遇到很多错误，他们错误信息并不一样，不都是“文件错误”。
//一种做法是每种错误都类似上面一样定义一个错误类型，然后在实现 Error() 方法时返回错误信息，但是这样太麻烦了。我们发现 Error() 返回的其实是个字符串，我们可以修改下，使得这个字符串可以让我们自己设置就可以了。

//方法二
//type fileError struct {
//	s string
//}
//
//func (fe *fileError) Error() string {
//	return fe.s
//}
//
//func openFile() ([]byte, error) {
//	return nil, &fileError{"文件错误，自定义"}
//}
//
//func main() {
//	conent, err := openFile()
//	if err != nil {
//		fmt.Println(err)
//	} else {
//		fmt.Println(string(conent))
//	}
//}

//这样的话只需要在调用 fileError 接口时，更改字符串就可以了。

// 方法三 通过创建新的辅助函数返回错误信息
// 现在我们可以把它变的更通用一些，比如修改fileError的名字，再 创建一个辅助函数 ，便于我们创建不同的错误类型。
func New(text string) error {
	return &errorString{text}
}

type errorString struct {
	s string
}

func (e *errorString) Error() string {
	return e.s
}
func openFile() ([]byte, error) {
	return nil, New("文件错误，自定义")
}

func main() {
	conent, err := openFile()
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Println(string(conent))
	}
}

/*
变成上面这样，我们就可以通过调用New函数，辅助我们创建不同的错误了，这其实就是我们经常用到的error.New() 函数，
被我们一步一步解析烟花而来，现在大家对于Go语言内置的error 有了一个清晰的认知了。

说到这里，我们不得不简单介绍一下errors.New():
error.New(): "error" 包中的一个内置方法New().使用的时候需要 import "error"
这是一种最基本的生成错误的方式。
调用它的时候传入一个字符串 代表错误信息，，他会给我们返回一个包含了这个错误信息的error类型值。
*/
